//package com.ys.server.gateway;
//
//import com.ys.common.verticle.BasicSocketVerticle;
//import io.vertx.core.Future;
//import io.vertx.core.buffer.Buffer;
//import io.vertx.core.net.NetSocket;
//import io.vertx.core.parsetools.RecordParser;
//import io.vertx.servicediscovery.Record;
//
//
//import com.google.protobuf.InvalidProtocolBufferException;
//import ByteUtils;
//import ServiceName;
//import com.ys.common.socket.SocketData;
//import com.ys.common.mq.EventMQ;
//
///**
// * Created by taotao on 2017/2/22.
// */
//public class SocketGateWayVerticle extends BasicSocketVerticle {
//
//    private static final int DEFAULT_PORT = 18181;
//
//    private EventMQ eventMQ;
//
//    private enum ProtoType {
//        TYPE, ID, LENGTH, CONTENT
//    }
//
///*
//    private int respLength = 0;
//    Buffer respBuffer;
//    private RecordParser respParser = RecordParser.newFixed(2, b->{
//
//    });*/
//
//
//    private ProtoType protoType = ProtoType.TYPE;
//
//    private int contentLength = 0;
//    private byte msgType = 0x00;
//    private short msgId = 0;
//    private RecordParser parser = RecordParser.newFixed(2, b -> {
//
//    });
//
//    @Override
//    public void start(Future<Void> future) throws Exception {
//        super.start();
//        eventMQ = EventMQ.getApiEventMQ(vertx);
//        this.createTcpServer(config().getInteger("port") != null ? config().getInteger("port") : DEFAULT_PORT, future);
//    }
//
//
//    protected void createTcpServer(int port, Future<Void> future) {
//
//        protoType = ProtoType.TYPE;
//
//        vertx.createNetServer().connectHandler(netSocket -> {
//            logger.info("client connect");
//            netSocket.handler(buffer -> {
//                parseRecord(netSocket);
//                parser.handle(buffer);
//            });
//        }).listen(port, res -> {
//            if (res.succeeded()) {
//                logger.info("Server start at " + port);
//                publishApiGateway("localhost", port);
//                future.complete();
//            } else {
//                logger.info("Failed to bind");
//                future.fail("Failed to start TCP:" + res.cause());
//            }
//        });
//
//    }
//
//
//    private void parseRecord(NetSocket netSocket) {
//        if (protoType == ProtoType.TYPE) {
//            parser.fixedSizeMode(1);
//            parser.setOutput(b -> {
//                msgType = b.getByte(0);
//                protoType = ProtoType.ID;
//                parseRecord(netSocket);
//            });
//        } else if (protoType == ProtoType.ID) {
//            parser.fixedSizeMode(2);
//            parser.setOutput(b -> {
//                msgId = b.getShort(0);
//                protoType = ProtoType.LENGTH;
//                parseRecord(netSocket);
//            });
//        } else if (protoType == ProtoType.LENGTH) {
//            parser.fixedSizeMode(4);
//            parser.setOutput(b -> {
//                contentLength = b.getInt(0);
//                if (contentLength > 0) {
//                    protoType = ProtoType.CONTENT;
//                    parseRecord(netSocket);
//                } else {
//                    byte[] contentBytes = new byte[0];
//                    SocketData socketData = SocketData.buildWithSocketData(msgType, msgId, contentLength, contentBytes);
//                    socketData.setSocketId(netSocket.writeHandlerID());
//                    handleSocketData(socketData, netSocket);
//                    protoType = ProtoType.TYPE;
//                    parseRecord(netSocket);
//                }
//
//            });
//        } else if (protoType == ProtoType.CONTENT) {
//            parser.fixedSizeMode(contentLength);
//            parser.setOutput(b -> {
//                byte[] contentBytes = b.getBytes();
//                SocketData socketData = SocketData.buildWithSocketData(msgType, msgId, contentLength, contentBytes);
//                socketData.setSocketId(netSocket.writeHandlerID());
//                handleSocketData(socketData, netSocket);
//                protoType = ProtoType.TYPE;
//                parseRecord(netSocket);
//            });
//        }
//    }
//
//    private void handleSocketData(SocketData socketData, NetSocket netSocket) {
//        try {
//            Future<SocketData> handlerFuture = Future.future();
//            dispatchRequest(socketData, handlerFuture);
//            handlerFuture.setHandler(ar -> {
//                if (ar.succeeded()) {
//                    SocketData respSocketData = ar.result();
//                    System.out.println("resp data:" + respSocketData);
//                    Buffer buffer = Buffer.buffer().appendBytes(respSocketData.byteArray());
//                    System.out.println(ByteUtils.bytesToHexString(respSocketData.byteArray()));
//                    netSocket.write(buffer);
//                } else {
//                    logger.error(ar.cause());
//                    SocketData respSocketData = SocketData.buildWithSocketData((byte) 0x00, (short) 0x0000, 2, new byte[]{0x08, 0x01});
//                    Buffer buffer = Buffer.buffer().appendBytes(respSocketData.byteArray());
//                    netSocket.write(buffer);
//                }
//            });
//            logger.debug("parse data end");
//        } catch (InvalidProtocolBufferException e) {
//            e.printStackTrace();
//        }
//    }
//
//    @Override
//    protected String name() {
//        return null;
//    }
//
//    @Override
//    protected void initDispatcher() {
//
//    }
//
//    protected void dispatchRequest(SocketData reqSocketData, Future<SocketData> handlerFuture) throws InvalidProtocolBufferException {
//        logger.info("gateway verticle handler request");
//
//        String serviceName = ServiceName.serviceNameMap.get(reqSocketData.getMsgId());
//        System.out.println("msg id is:" + ByteUtils.bytesToHexString((reqSocketData.getMsgId())) + ",dispatch to verticle:" + serviceName);
//        discovery.getRecord(r -> r.getName().equals(serviceName), ar -> {
//            if (ar.succeeded()) {
//                if (ar.result() != null) {
//                    Record record = ar.result();
//                    String address = record.getLocation().getString("address");
//                    eventMQ.send(address, reqSocketData, respData -> handlerFuture.complete(respData));
//                } else {
//                    logger.error("client service:no match service verticle address");
//                    handlerFuture.fail("client service:no match service verticle address");
//                }
//            } else {
//                logger.error(ar.cause());
//                handlerFuture.fail(ar.cause());
//            }
//        });
//
//
//        /*
//        NetClientOptions options = new NetClientOptions().setConnectTimeout(10000);
//        NetClient client = vertx.createNetClient(options);
//
//        client.connect(18182, "localhost", res -> {
//            if (res.succeeded()) {
//                System.out.println("Connected to Detail Verticle!");
//                NetSocket socket = res.result();
//                Buffer reqBuffer = Buffer.buffer(reqSocketData.byteArray());
//                socket.write(reqBuffer);
//                socket.handler(respBuffer -> {
//                    parseRespRecord(handlerFuture,client);
//                    respParser.handle(respBuffer);
//                });
//            } else {
//                System.out.println("Failed to connect: " + res.cause().getMessage());
//            }
//        });*/
//    }
//
//    /*
//    返回消息的分包处理
//
//    private void parseRespRecord(Future<SocketData> handlerFuture, NetClient client){
//        if(protoType==ProtoType.TYPE){
//            respParser.fixedSizeMode(3);
//            respParser.setOutput(b->{
//                respBuffer = Buffer.buffer();
//                respBuffer.appendByte(b.getByte(0));
//                respBuffer.appendShort(b.getShort(1));
//                protoType=ProtoType.LENGTH;
//                parseRespRecord(handlerFuture,client);
//            });
//        }else if(protoType==ProtoType.LENGTH){
//            respParser.fixedSizeMode(4);
//            respParser.setOutput(b->{
//                respLength = b.getInt(0);
//                respBuffer.appendInt(respLength);
//                protoType=ProtoType.CONTENT;
//                parseRespRecord(handlerFuture,client);
//            });
//        }else if(protoType==ProtoType.CONTENT){
//            respParser.fixedSizeMode(respLength);
//            respParser.setOutput(b->{
//                byte[] contentBytes = b.getBytes();
//                respBuffer.appendBytes(contentBytes);
//                SocketData respSocketData = SocketData.buildWithRawData(respBuffer.getBytes());
//                client.close(); //发完关闭
//                handlerFuture.complete(respSocketData);
//                protoType=ProtoType.TYPE;
//                parseRespRecord(handlerFuture,client);
//            });
//        }
//    }*/
//}
